<template>
  <t-popup
    placement="bottom"
    destroy-on-close
    trigger="click"
    :visible="popupVisible"
  >
    <slot>
      <t-button @click="onToggle" theme="default" v-bind="buttonOptions">
        <template #icon>
          <SettingIcon />
        </template>
        列配置
      </t-button>
    </slot>
    <template #content>
      <Draggable
        :columns-list="displayColumns"
        @changeCloumnsConfig="changeCloumnsConfig"
        @resetColumns="resetColumns"
        @submitColumns="submitColumns"
      ></Draggable>
    </template>
  </t-popup>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive, nextTick, computed } from "vue";
import Draggable from "./column-set.vue";
import { SettingIcon } from "tdesign-icons-vue-next";
import { COLUMNS_SHOW_FORMAT } from "./type";
import { debounce, isEmpty, isLength } from "lodash";
import { PrimaryTableCol, TableRowData } from "tdesign-vue-next";

const props = defineProps<{
  columnsList: any[];
  buttonOptions?: any;
  name: string;
}>();

const displayColumns = ref<COLUMNS_SHOW_FORMAT[]>([]);

// 获取localStorage中的列配置
const localKey = computed(() => {
  return `userColumnsSet_${props.name}`;
});

const emit = defineEmits(["changeColumns"]);

// 初始化存储列数据
const saveColumnsData = () => {
  const fixedData: string[] = [];
  const unCheckData: string[] = [];
  displayColumns.value.forEach((item) => {
    if (item.isFixed) {
      fixedData.push(item.name);
    } else if (!item.check) {
      unCheckData.push(item.name);
    }
  });
  const userColumnsSetData = {
    fixedData,
    unCheckData,
    order: displayColumns.value.map((item) => item.name),
  };
  localStorage.setItem(localKey.value, JSON.stringify(userColumnsSetData));
};
const initColumns = () => {
  // 列配置展开详情的部分
  displayColumns.value = props.columnsList.map((item) => {
    return {
      name: item.title,
      check: item.check ?? true,
      isFixed: item.isFixed ?? false,
    };
  });
  // 看本地有没有配置
  const userColumnsSet = localStorage.getItem(localKey.value);
  // 如果没有列配置或者是重置
  if (!userColumnsSet) {
    saveColumnsData();
  } else {
    const { fixedData, unCheckData, order } = JSON.parse(userColumnsSet);
    // 有顺序，根据顺序排序
    const list = new Array(
      Math.max(order.length, displayColumns.value.length)
    ).fill(null);
    // 复制一份(记录的值)
    let displayColumnsCopyValue = [...displayColumns.value];
    // 记录没有进行赋值的数值
    const unAssignData: string[] = [];
    // 上一个被赋值的值
    let lastValData = "";
    for (let i = 0; i < displayColumns.value.length; i++) {
      const item = displayColumns.value[i];
      const findIndex = order.findIndex(
        (orderItem: string) => orderItem === item.name
      );
      // 这里排除了当次列的数量比order的情况
      if (~findIndex) {
        list[findIndex] = item;
        // 将赋值进去的给删掉
        displayColumnsCopyValue = displayColumnsCopyValue.filter(
          (i) => i.name !== item.name
        );
        lastValData = item.name;
      } else {
        unAssignData.push(lastValData);
      }
    }
    // 复制一份unAssignData
    const unAssignDataCopy = [...unAssignData];
    // 将list中的null去除
    const filterNullList = list.filter((i) => i);
    // 此时还有可能displayColumnsCopyValue中还有一些列没有在order中，按照指定顺序操作(用来避免当次列的数量比order多或者名称变化的情况)
    while (unAssignData.length > 0 && displayColumnsCopyValue.length > 0) {
      const item = displayColumnsCopyValue.shift();
      const lastVal = unAssignData.shift();
      // 如果没有lastVal，说明是第一个
      if (!lastVal) {
        filterNullList.unshift(item);
        break;
      }
      // 根据lastVal找到插入filterNullList的位置
      const findIndex = filterNullList.findIndex((i) => i.name === lastVal);
      filterNullList.splice(findIndex + 1, 0, item);
    }
    displayColumns.value = filterNullList.map((item) => {
      // 说明是代码里面操作过的列
      if (unAssignDataCopy.includes(item.name)) {
        return {
          ...item,
          check: item.check ?? true,
          isFixed: item.isFixed ?? false,
        };
      }
      return {
        ...item,
        check: !unCheckData.includes(item.name),
        isFixed: fixedData.includes(item.name),
      };
    });
    // 长度不相等或者数据修改了，需要重新赋值
    const isLengthEqual = displayColumns.value.length === order.length;
    if (!isEmpty(unAssignDataCopy) || !isLengthEqual) {
      saveColumnsData();
    }
  }
  changeCloumnsConfig(displayColumns.value);
};

onMounted(() => {
  initColumns();
});

const curColumnData = reactive({
  fixedData: [], // 固定列数据
  unCheckData: [], // 隐藏列数据
  order: [], // 列顺序
});

const changeCloumnsConfig = (list: COLUMNS_SHOW_FORMAT[]) => {
  // 重置数据
  curColumnData.fixedData = [];
  curColumnData.unCheckData = [];
  curColumnData.order = [];
  // 当前变化的list
  const changeList = [...list];
  // 原先的table列
  const originColumns = [...props.columnsList];
  // 新的table列
  const newColumns: PrimaryTableCol<TableRowData>[] = [];
  // 重新设置列
  changeList.forEach((item) => {
    const findItemIndex = originColumns.findIndex((i) => i.title === item.name);
    if (~findItemIndex) {
      const curData = originColumns[findItemIndex];
      // 删除当前index的数据，减少下一次循环查找次数
      originColumns.splice(findItemIndex, 1);
      curColumnData.order.push(item.name);
      const isFixed = item.isFixed ? "left" : undefined;
      if (isFixed) {
        curColumnData.fixedData.push(item.name);
      }
      if (item.check) {
        newColumns.push({
          ...curData,
          fixed: isFixed,
        });
      } else {
        console.log(item.name, "隐藏的列");
        // 隐藏的列
        curColumnData.unCheckData.push(item.name);
      }
    }
  });
  //   console.log(newColumns,'newColumns')
  displayColumns.value = changeList;
  emit("changeColumns", isEmpty(newColumns) ? props.columnsList : newColumns);
};

const popupVisible = ref(false);

const onToggle = debounce(() => {
  popupVisible.value = !popupVisible.value;
}, 100);

// 子组件提交确认
const submitColumns = () => {
  popupVisible.value = false;
  saveUserColumns();
};

// 重置列
const resetColumns = async () => {
  // 去除localStorage的值
  localStorage.removeItem(localKey.value);
  // 重新初始化
  initColumns();
};
// 保存列
const saveUserColumns = async () => {
  const { fixedData, unCheckData, order } = curColumnData;
  // 本地保存列
  localStorage.setItem(
    localKey.value,
    JSON.stringify({
      fixedData,
      unCheckData,
      order,
    })
  );
};

defineExpose({
  onToggle,
});
</script>
